package service

import (
	"context"
	"github.com/star-find-cloud/star-chat/internal/mq"
	log "github.com/star-find-cloud/star-chat/pkg/logger"
	"github.com/star-find-cloud/star-chat/rule/domain"
	"github.com/star-find-cloud/star-chat/rule/repo"
	"time"
)

type RuleServiceImpl struct {
	repo         repo.RoleRepository
	cache        repo.RoleCache
	orchestrator repo.RuleOrchestrator
}

func NewRuleService(repo repo.RoleRepository, cache repo.RoleCache, orchestrator repo.RuleOrchestrator, producer mq.ProducerSrv, txProducer mq.TXProducer) RuleService {
	return &RuleServiceImpl{
		repo:         repo,
		cache:        cache,
		orchestrator: orchestrator,
	}
}

func (r *RuleServiceImpl) Create(ctx context.Context, rule *domain.Rule) (int64, error) {
	exists, err := r.repo.IsExistByName(ctx, rule.Name)
	if err != nil {
		return 0, newSrvError(CodeDatabaseError, "server error", err, "create")
	}
	if exists {
		return 0, newSrvError(CodeExist, "rule is exist", nil, "create")
	}

	if rule.Name == "" {
		return 0, newSrvError(CodeInvalidObject, "rule invalid", nil, "create")
	}

	id, err := r.repo.Create(ctx, rule)
	if err != nil {
		log.AppLogger.Errorf("create rule failed: %v", err)
		return 0, newSrvError(CodeDatabaseError, "server error", err, "create")
	}

	err = r.cache.MakeRuleCache(ctx, id, rule)
	if err != nil {
		for i := 1; i <= 3; i++ {
			sleepTime := i * i
			time.Sleep(time.Duration(sleepTime) * time.Second)
			if err := r.cache.MakeRuleCache(ctx, id, rule); err == nil {
				break
			}
			log.AppLogger.Warnf("retry make rule cache %d failed: %v", i, err)
			if i == 3 {
				log.AppLogger.Errorf("final retry failed: %v", err)
				return 0, newSrvError(CodeCacheError, "server error", err, "make cache")
			}
		}
	}

	log.AppLogger.Infof("rule create success, rule: %v", rule)
	return id, nil
}

func (r *RuleServiceImpl) Get(ctx context.Context, id int64) (*domain.Rule, error) {
	if id < 100 {
		return nil, newSrvError(CodeNotFound, "rule not found", nil, "get")
	}
	//TODO implement me
	panic("implement me")
}

func (r *RuleServiceImpl) GetAll(ctx context.Context) ([]*domain.Rule, error) {
	//TODO implement me
	panic("implement me")
}

func (r *RuleServiceImpl) Update(ctx context.Context, rule *domain.Rule) error {
	//TODO implement me
	panic("implement me")
}

func (r *RuleServiceImpl) Enable(ctx context.Context, id int64) error {
	//TODO implement me
	panic("implement me")
}

func (r *RuleServiceImpl) Disable(ctx context.Context, id int64) error {
	//TODO implement me
	panic("implement me")
}

func (r *RuleServiceImpl) Delete(ctx context.Context, id int64) error {
	//TODO implement me
	panic("implement me")
}

func (r *RuleServiceImpl) IsExist(ctx context.Context, id int64) (bool, error) {
	//TODO implement me
	panic("implement me")
}
